/**
 * @file    Genetic.h
 * @brief   
 *
 * \warning AI Framework is under planning, this source file may be a preliminary test.
 *
 ****************************************************************************
 * @version 0.8.384 $Id: Genetic.h 2420 2010-05-05 15:44:31Z alex $
 * @author  Alessandro Polo
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

#ifndef __WOSH_AI_Genetic_H__
 #define __WOSH_AI_Genetic_H__

 #include <woshDefs.h>
 
namespace wosh {
 namespace ai {

/*
GOAL::
 - initial population (Genome<T>)
 - fitness function
  -> solution(s)

 - initial population (IGenome)
  -> solution

IGenome

*/

class IGenome {
	public:
		virtual float getFitness() const = 0;

	public:
		virtual ~IGenome() { }

};


template <typename T>
class Genome<T> : public virtual IGenome {
	public:
	//	virtual float getFitness() const = 0;
	public:
		const T getObject() const		{ return this->object; }
		T getObject()					{ return this->object; }

	public:
		Genome() {
			this->object = NULL;
		 }
		virtual ~Genome() { }

	protected:
		T object;

};



class GeneticEngine {

	public:
		GeneticEngine() {

			Log.setContext( "GeneticEngine" );
			Log.setIndent( 3 );
			Log.setLevel( INFO );
			Log.setLevel( VERBOSE );

			this->populationSize = 30;
			this->generationsNumber = 400;
			this->mutationParam = 0.001;
			this->crossoverParam = 0.9;

		 }

		virtual ~GeneticEngine() {
		 }


	public:

		void evolve() {
			Log(LOG_INFO, ":evolve(%i,%i,%f,%f)", this->populationSize, this->generationsNumber, this->mutationParam, this->crossoverParam );


			GASimpleGA ga(genome);
			ga.populationSize(this->populationSize);
			ga.nGenerations(this->generationsNumber);
			ga.pMutation(this->mutationParam);
			ga.pCrossover(this->crossoverParam);

			ga.evolve();


		 }

// ga.statistics().bestIndividual()
  

	public:
		int getPopulationSize()					{ return this->populationSize; }
		int getGenerationsNumber()				{ return this->generationsNumber; }
		float getMutationParam()				{ return this->mutationParam; }
		float getCrossoverParam()				{ return this->crossoverParam; }


	public:
		void setPopulationSize( int value )		{ this->populationSize = value; }
		void setGenerationsNumber( int value )	{ this->generationsNumber = value; }
		void setMutationParam( float value )	{ this->mutationParam = value; }
		void setCrossoverParam( float value )	{ this->crossoverParam = value; }

//		void set()	{ this-> = value; }



	protected:
		int populationSize;
		int generationsNumber;
		float mutationParam;
		float crossoverParam;

		Logger Log;

}; // class def
 
 
  

/*
double calculateFitness( cromosoma, oggetto ) // ,obbiettivi globali 
 {

 }


http://improve.dk/blog/2009/04/29/implementing-a-simple-genetic-algorithm
By Mark S. Rasmussen

we have an interface that represents a basic chromosome. In this implementation, a chromosome is basically a candidate solution. The chromosome is also the type that implements the fitness function, to evaluate it's own correctness. The fitness is returned as an arbitrary double value, the higher the value the better a candidate. The ChromosomeValue property is the actual value being tested - in this case, an instance of Rgb.

class IChromosome<T> {
	public:
		double getFitness() const = 0;
		T ChromosomeValue() const = 0;

	public:
		virtual ~IChromosome() { }

}; // class def


*/


 }; // namespace ai
}; // namespace wosh

#endif //__WOSH_AI_Genetic_H__
